package com.xebest.web.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xebest.common.enums.erp.aftersales.*;
import com.xebest.common.enums.erp.sys.VenDelEnum;
import com.xebest.util.Money;
import com.xebest.util.seq.FinanceSeqUtil;
import com.xebest.util.seq.StoreHouseSeqUtil;
import com.xebest.web.form.*;
import com.xebest.web.mapper.read.*;
import com.xebest.web.mapper.write.*;
import com.xebest.web.model.*;
import com.xebest.web.service.XeVenAfterSaleService;
import com.xebest.web.view.*;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @desc:
 * @author: chenjing
 * @createTime: 2017/6/20 0020 下午 8:42
 * @history:
 * @version:v1.0
 */
@Service
public class XeVenAfterSaleServiceImpl implements XeVenAfterSaleService {
    private static Logger log = LoggerFactory.getLogger(XeVenAfterSaleServiceImpl.class);

    @Autowired
    private XeVenAfterSaleReadMapper readMapper;
    @Autowired
    private XeVenAfterSaleWriterMapper writerMapper;
    @Autowired
    private XeVenAfterSaleImgWriterMapper xeVenAfterSaleImgWriterMapper;
    @Autowired
    private XeVenAfterSaleImgReadMapper xeVenAfterSaleImgReadMapper;
    @Autowired
    private XeVenGoodsRejectWriteMapper rejectWriterMapper;
    @Autowired
    private XeVenGoodsRejectDetailWriteMapper rejectDetailWriteMapper;
    @Autowired
    private XeVenOrderRefundWriteMapper refundWriteMapper;
    @Autowired
    private XeVenGoodsRejectReadMapper rejectReadMapper;
    @Autowired
    private XeVenOrderRefundReadMapper refundReadMapper;
    @Autowired
    private StoreHouseSeqUtil storeHouseSeqUtil;
    @Autowired
    private FinanceSeqUtil financeSeqUtil;
    @Autowired
    private XeVenAfterSaleDetailWriteMapper afterSaleDetailWriteMapper;
    @Autowired
    private XeVenAfterSaleDetailReadMapper afterSaleDetailReadMapper;
    @Autowired
    private XeVenOrderRefundDetailWriteMapper orderRefundDetailWriterMapper;
    @Autowired
    private XeVenOrderReadMapper orderReadMapper;


    /**
     * @Author:chenjing
     * @Description: 根据查询条件查询售后单列表
     * @Date:下午 8:43 2017/6/20 0020
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenAfterSaleView> queryAfterSaleList(XeVenAfterSaleQueryForm entity) throws Exception {
        return readMapper.queryAfterSaleList(entity);
    }

    /**
     * @Author:chenjing
     * @Description: 根据售后单编号删除售后单（不用）
     * @Date:下午 8:43 2017/6/20 0020
     * @params: * @param null
     * @return:
     */
    @Override
    public int deleteByAfterSalesCode(XeVenAfterSaleEntity entity) throws Exception {
        int flag = 0;
        int afterSaleType = entity.getAfterSaleType();
        String userCode = entity.getUserCode();
        String userName = entity.getModifyUser();
        //删除售后单对应的退货单，退货单明细，退款单，退款单明细
        /**
         * 如果售后单为仅退款，则删除退款单信息
         * 如果售后单为退货退款，则删除退货单，退款单
         */
        if (VenAfterSaleTypeEnum.REJECT.getValue().equals(afterSaleType)) {
            XeVenGoodsRejectEntity rejectEntity = rejectReadMapper.selectByAfterSalesCode(entity.getAfterSalesCode(), userCode);
            if (null == rejectEntity) {
                log.error("删除退货单失败，未查到退货单信息,{}", ToStringBuilder.reflectionToString(entity));
                throw new Exception();
            }
            //删除退货单
            rejectEntity.setModifyUser(userName);
            rejectEntity.setDelFlag(VenDelEnum.YES.getValue());
            flag = rejectWriterMapper.updateByRejectInfo(rejectEntity);
            if (flag <= 0) {
                log.error("删除退货单信息失败，{}" + ToStringBuilder.reflectionToString(rejectEntity));
                throw new Exception();
            }
            //插入退货单日志 // TODO: 2017/6/23 0023  插入退货单日志
        }
        //删除退款单
        XeVenOrderRefundEntity refundEntity = refundReadMapper.selectByAfterSalesCode(entity.getAfterSalesCode());
        if (null == refundEntity) {
            log.error("删除退款单失败，未查到退款单信息，{}" + ToStringBuilder.reflectionToString(refundEntity));
            throw new Exception();
        }
        refundEntity.setModifyUser(userName);
        refundEntity.setDelFlag(VenDelEnum.YES.getValue());
        flag = refundWriteMapper.updateByOrderRefundInfo(refundEntity);
        if (flag <= 0) {
            log.error("删除退款单信息失败，{}" + ToStringBuilder.reflectionToString(refundEntity));
            throw new Exception();
        }
        //插入退款单日志  // TODO: 2017/6/23 0023 插入退款单日志

        //删除售后单
        flag = writerMapper.deleteByAfterSalesCode(entity.getAfterSalesCode());
        // TODO: 2017/6/23 0023  插入售后单日志

        return flag;
    }

    @Override
    public int cancelAfterSale(XeVenAfterSaleEntity entity) throws Exception {
        return writerMapper.updateByPrimaryKey(entity);
    }

    /**
     * @param record              售后单封装后实体
     * @param list                售后类型为退货退款，存放商品sku和退货数量
     * @param orderInfoDetailList 对应的订单明细信息
     * @Author:chenjing
     * @Description:插入售后单信息
     * @Date:下午 8:44 2017/6/20 0020
     * @return:
     */
    @Transactional(value = "writeTransactionManager")
    @Override
    public int insertAfterSale(XeVenAfterSaleEntity record, List<XeVenAfterSaleDetailEntity> list, List<XeVenOrderInfoDetailEntity> orderInfoDetailList) throws Exception {
        int flag = 0;
        // TODO: 2017/6/23 0023  插入售后单日志信息
        //插入售后单日志信息

        //插入售后单信息
        flag = writerMapper.insert(record);
        if (flag <= 0) {
            log.error("插入售后单信息失败,{}", ToStringBuilder.reflectionToString(record));
            throw new Exception();
        }
        List<String> imgs = record.getImgs();
        if (imgs != null && imgs.size() > 0) {//如果有图片附件地址则保存到数据库中
            //新增图片
            String afterSalesCode = record.getAfterSalesCode();
            xeVenAfterSaleImgWriterMapper.insertImgs(afterSalesCode, imgs);
        }
        /**
         * 插入售后单明细信息
         */
        // BigDecimal refundAmount = record.getRefundAmount(); //退款金额
        //售后单明细List 便于批量插入信息
        List<Map<String, Object>> afterSaleDetailEntities = new ArrayList<Map<String, Object>>();
        /**
         //如果售后类型为仅退款
         DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
         //设置精确几位小数
         df.setMaximumFractionDigits(1);
         //模式四舍五入
         df.setRoundingMode(RoundingMode.HALF_UP);
         int i = orderInfoDetailList.size();
         // 如果为最后一项商品，不计算占比金额，利用总退款金额-前面商品已占退款金额=该商品的退款金额
         //商品已占退款金额
         BigDecimal realRejectAmount = new BigDecimal(0);
         int j = 0;
         **
         if(VenAfterSaleTypeEnum.REFUND.getValue().equals(record.getAfterSaleType())){
         for (XeVenOrderInfoDetailEntity orderDetailView:orderInfoDetailList) {
         // j++;
         XeVenAfterSaleDetailEntity detailEntity;
         String jsonString  = JSON.toJSONString(orderDetailView, SerializerFeature.WriteMapNullValue,
         SerializerFeature.WriteNullStringAsEmpty);
         detailEntity = JSON.parseObject(jsonString,XeVenAfterSaleDetailEntity.class);
         detailEntity.setAfterSalesCode(record.getAfterSalesCode());
         detailEntity.setRejectNum(new BigDecimal(0)); //退货数量
         detailEntity.setRemark(""); //售后备注
         /**
         if(j!=i){
         //退货金额=当前商品实付金额与订单支付金额的比例 乘以 售后单退款金额
         //占比   // TODO: 2017/7/4 0004 占比计算公式
         String accuracy = df.format(orderDetailView.getProPayAmount().doubleValue()/payAmount.doubleValue());
         //退货金额
         BigDecimal rejectAmount  = Money.of(refundAmount).multiply(new BigDecimal(accuracy)).toStoreDecimal();
         detailEntity.setRejectAmount(rejectAmount);
         //已经占比的退货金额
         realRejectAmount = Money.of(realRejectAmount).plus(rejectAmount).toStoreDecimal();
         }else{
         //退货金额
         BigDecimal rejectAmount = Money.of(refundAmount).minus(realRejectAmount).toStoreDecimal();
         detailEntity.setRejectAmount(rejectAmount); //退货金额
         }
         **
         jsonString  = JSON.toJSONString(detailEntity, SerializerFeature.WriteMapNullValue,
         SerializerFeature.WriteNullStringAsEmpty);
         Map<String ,Object> detailMap = JSON.parseObject(jsonString,Map.class);
         afterSaleDetailEntities.add(detailMap);
         }
         }
         **/


        for (XeVenAfterSaleDetailEntity detailEntity : list) {
            //本次退货数量
            BigDecimal rejectNum = detailEntity.getRejectNum();
            rejectNum = null == rejectNum ? new BigDecimal(0) : rejectNum;
            //本次退货金额
            BigDecimal rAmount = detailEntity.getRejectAmount();
            rAmount = null == rAmount ? new BigDecimal(0) : rAmount;
            if (Money.of(rejectNum).compareTo(Money.of(new BigDecimal(0))) == 0
                    && Money.of(rAmount).compareTo(Money.of(new BigDecimal(0))) == 0) {
                continue;
            }
            for (XeVenOrderInfoDetailEntity orderDetailView : orderInfoDetailList) {
                if (orderDetailView.getProSku().equals(detailEntity.getProSku())) {
                    String jsonString = JSON.toJSONString(orderDetailView, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty);
                    XeVenAfterSaleDetailEntity newDetailEntity = JSON.parseObject(jsonString, XeVenAfterSaleDetailEntity.class);
                    //newDetailEntity.setProCostPrice(orderDetailView.getProPrice());
                    newDetailEntity.setAfterSalesCode(record.getAfterSalesCode());
                    newDetailEntity.setRemark(""); //售后备注
                    //如果售后类型为退货退款
                    if (VenAfterSaleTypeEnum.REJECT.getValue().equals(record.getAfterSaleType())) {
                        //退货金额=退货数量*商品优惠后单价
                        newDetailEntity.setRejectNum(rejectNum); //退货数量
                        BigDecimal rejectAmount = Money.of(rejectNum).multiply(orderDetailView.getProCostPrice()).toStoreDecimal();
                        newDetailEntity.setRejectAmount(rejectAmount);
                    } else if (VenAfterSaleTypeEnum.REFUND.getValue().equals(record.getAfterSaleType())) {
                        newDetailEntity.setRejectNum(new BigDecimal(0));
                        newDetailEntity.setRejectAmount(detailEntity.getRejectAmount());
                    }
                    jsonString = JSON.toJSONString(newDetailEntity, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty);
                    Map<String, Object> detailMap = JSON.parseObject(jsonString, Map.class);
                    afterSaleDetailEntities.add(detailMap);
                }
            }
        }
        if (afterSaleDetailEntities.size() == 0) {
            log.error("售后明细插入失败,未查询到对应数据！");
            throw new Exception();
        }
        //插入售后单明细
        flag = afterSaleDetailWriteMapper.insertAllAfterSaleDetail(afterSaleDetailEntities);
        return flag;
    }

    /**
     * @param record              售后单封装后实体
     * @param list                售后类型为退货退款，存放商品sku和退货数量
     * @param orderInfoDetailList 对应的订单明细信息
     * @Author:chenjing
     * @Description:编辑售后单信息
     * @Date:下午 8:44 2017/6/20 0020
     * @return:
     */
    @Transactional(value = "writeTransactionManager")
    @Override
    public int updateAfterSale(XeVenAfterSaleEntity record, List<XeVenAfterSaleDetailEntity> list, List<XeVenOrderInfoDetailEntity> orderInfoDetailList) throws Exception {
        int flag = 0;
        // TODO: 2017/6/23 0023  编辑售后单日志信息
        //编辑售后单日志信息

        //编辑售后单信息
        flag = writerMapper.updateByPrimaryKey(record);
        if (flag <= 0) {
            log.error("编辑售后单信息失败,{}", ToStringBuilder.reflectionToString(record));
            throw new Exception();
        }
        //将原来的图片设置为删除状态
        String afterSalesCode = record.getAfterSalesCode();
        xeVenAfterSaleImgWriterMapper.delImgsByAfterSaleCode(afterSalesCode);
        List<String> imgs = record.getImgs();
        if (imgs != null && imgs.size() > 0) {//如果有图片附件地址则保存到数据库中
            xeVenAfterSaleImgWriterMapper.insertImgs(afterSalesCode, imgs);
        }


        //删除相关的售后单明细信息
        flag = afterSaleDetailWriteMapper.delAfterSaleDetail(record.getAfterSalesCode());
        if (flag <= 0) {
            log.error("删除售后单明细信息失败,售后单号={}", record.getAfterSalesCode());
            throw new Exception();
        }
        /**
         * 编辑售后单明细信息
         */
        //售后单明细List 便于批量插入信息
        List<Map<String, Object>> afterSaleDetailEntities = new ArrayList<Map<String, Object>>();


        for (XeVenAfterSaleDetailEntity detailEntity : list) {
            for (XeVenOrderInfoDetailEntity orderDetailView : orderInfoDetailList) {
                if (orderDetailView.getProSku().equals(detailEntity.getProSku())) {
                    String jsonString = JSON.toJSONString(orderDetailView, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty);
                    XeVenAfterSaleDetailEntity newDetailEntity = JSON.parseObject(jsonString, XeVenAfterSaleDetailEntity.class);
                    newDetailEntity.setAfterSalesCode(record.getAfterSalesCode());
                    newDetailEntity.setRemark(""); //售后备注
                    //如果售后类型为退货退款
                    if (VenAfterSaleTypeEnum.REJECT.getValue().equals(record.getAfterSaleType())) {
                        //退货数量
                        BigDecimal rejectNum = detailEntity.getRejectNum();
                        //退货金额=退货数量*商品成交价
                        newDetailEntity.setRejectNum(rejectNum); //退货数量
                        BigDecimal rejectAmount = Money.of(rejectNum).multiply(orderDetailView.getProCostPrice()).toStoreDecimal();
                        newDetailEntity.setRejectAmount(rejectAmount);
                    } else if (VenAfterSaleTypeEnum.REFUND.getValue().equals(record.getAfterSaleType())) {
                        newDetailEntity.setRejectNum(new BigDecimal(0));
                        newDetailEntity.setRejectAmount(detailEntity.getRejectAmount());
                    }
                    jsonString = JSON.toJSONString(newDetailEntity, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty);
                    Map<String, Object> detailMap = JSON.parseObject(jsonString, Map.class);
                    afterSaleDetailEntities.add(detailMap);
                }
            }
        }
        if (afterSaleDetailEntities.size() == 0) {
            log.error("售后明细插入失败,未查询到对应数据！");
            throw new Exception();
        }
        //插入售后单明细
        flag = afterSaleDetailWriteMapper.insertAllAfterSaleDetail(afterSaleDetailEntities);
        return flag;
    }


    /**
     * @Author:chenjing
     * @Description:根据orderId查询订单详细信息
     * @Date:下午 8:00 2017/6/22 0022
     * @params: * @param null
     * @return:
     */
    @Override
    public XeVenOrderInfoEntity queryOrderInfoByOrderId(String orderId, String userCode) {
        return readMapper.queryOrderInfoByOrderId(orderId, userCode);
    }

    /**
     * @Author:chenjing
     * @Description: 根据售后单号查询售后单信息
     * @Date:下午 1:44 2017/6/23 0023
     * @params: * @param null
     * @return:
     */
    @Override
    public XeVenAfterSaleEntity selectByPrimaryKey(String afterSalesCode, String userCode) {
        return readMapper.selectByPrimaryKey(afterSalesCode, userCode);
    }

    /**
     * @Author:chenjing
     * @Description:更新售后单信息
     * @Date:下午 2:05 2017/6/23 0023
     * @params: * @param null
     * @return:
     */
    @Transactional(value = "writeTransactionManager")
    @Override
    public int updateByPrimaryKey(XeVenAfterSaleEntity record) throws Exception {
        int flag = 0;
        String userCode = record.getUserCode();
        //更新售后单信息
        flag = writerMapper.updateByPrimaryKey(record);
        if (flag <= 0) {
            log.error("更新售后单信息失败,{}", ToStringBuilder.reflectionToString(record));
            throw new Exception();
        }
        //插入售后单日志   // TODO: 2017/6/23 0023 插入售后单日志
        //如果售后单审核状态不为已审核，直接返回
        if (!VenAfterSaleStatusEnum.PASS.getValue().equals(record.getAfterSaleStatus())) {
            return flag;
        }

        List<XeVenAfterSaleDetailEntity> afterSaleDetailList = afterSaleDetailReadMapper.queryAfterSaleDetailList(record.getAfterSalesCode());
        if (afterSaleDetailList.size() <= 0) {
            log.error("查询售后单明细异常，结果为空，售后单id={}", ToStringBuilder.reflectionToString(record.getAfterSalesCode()));
            throw new Exception();
        }

        /**
         * 如果为审核通过
         * 1,如果为仅退款，则生成退款单信息 和退款明细信息（根据售后明细）
         * 2,如果为退款并退货 则生成退货单信息和退货单明细信息（根据售后明细）
         *
         */
        int afterSaleType = record.getAfterSaleType();
        //仅退款
        if (VenAfterSaleTypeEnum.REFUND.getValue().equals(afterSaleType)) {
            //生成退款单信息
            XeVenOrderRefundEntity refundEntity = new XeVenOrderRefundEntity();
            String refundCode = financeSeqUtil.createRefundCode(); //退款单号
            refundEntity.setAfterSalesCode(record.getAfterSalesCode());//售后单号
            refundEntity.setOrderId(record.getOrderId()); //订单号
            refundEntity.setRefundSource(VenOrderRefundSourceEnum.AFTER_SALE.getValue());  //退款单来源 2售后创建
            refundEntity.setRefundCode(refundCode);  //退款单号
            refundEntity.setRefundedAmount(new BigDecimal(0)); //已退款金额
            refundEntity.setRealRefundedAmount(record.getRefundAmount()); //退款金额
            refundEntity.setRefundType(VenOrderRefundTypeEnum.AFTERSALERFUND.getValue());   //退款类型 3 仅退款
            refundEntity.setRefundReason(VenOrderRefundReasonEnum.NO_REISION.getValue());//退款原因
            refundEntity.setRefundStatus(VenOrderRefundStatusEnum.PENDING.getValue()); //退款状态
            refundEntity.setCreateUser(record.getModifyUser());
            refundEntity.setModifyUser(record.getModifyUser());
            refundEntity.setDelFlag(VenDelEnum.NO.getValue());
            refundEntity.setUserCode(userCode);
            flag = refundWriteMapper.insert(refundEntity);
            if (flag <= 0) {
                log.error("插入退款单信息失败!{}", ToStringBuilder.reflectionToString(refundEntity));
                throw new Exception();
            }

            //退款单明细批量插入List
            List<Map<String, Object>> orderRefundDetailList = new ArrayList<>();

            //生成并插入退款明细信息
            for (XeVenAfterSaleDetailEntity afterSaleDetail : afterSaleDetailList) {
                XeVenOrderRefundDetailEntity orderRefundDetail = new XeVenOrderRefundDetailEntity();
                orderRefundDetail.setRefundCode(refundCode); //退款单号
                orderRefundDetail.setProSku(afterSaleDetail.getProSku()); //商品sku
                orderRefundDetail.setBuyNums(afterSaleDetail.getPurchaseNum()); //购买数量
                orderRefundDetail.setRejectNums(afterSaleDetail.getRejectNum()); //退货数量（如果为售后单为仅退款，则此处为0）
                orderRefundDetail.setRefundAmount(afterSaleDetail.getRejectAmount()); //退款金额
                Map afterSaleDetailMap = JSON.parseObject(JSON.toJSONString(orderRefundDetail, SerializerFeature.WriteMapNullValue,
                        SerializerFeature.WriteNullStringAsEmpty), Map.class);
                orderRefundDetailList.add(afterSaleDetailMap);
            }
            //插入退款明细信息
            flag = orderRefundDetailWriterMapper.insertAllOrderRefundDetail(orderRefundDetailList);
            if (flag <= 0) {
                log.error("插入退款单明细失败！{}", ToStringBuilder.reflectionToString(orderRefundDetailList));
                throw new Exception();
            }
            // TODO: 2017/6/23 0023  插入退款单日志
        }

        //退货退款
        if (VenAfterSaleTypeEnum.REJECT.getValue().equals(afterSaleType)) {
            String rejectCode = storeHouseSeqUtil.createRejectCode();
            //插入退货单信息
            XeVenGoodsRejectEntity rejectEntity = new XeVenGoodsRejectEntity();
            rejectEntity.setAfterSalesCode(record.getAfterSalesCode());  //售后单号
            rejectEntity.setRejectCode(rejectCode);
            //供应商编码
            rejectEntity.setUserCode(userCode);
            rejectEntity.setOrderId(record.getOrderId());  //订单号
            rejectEntity.setStoreId(record.getStoreId()); //退货仓库标识
            rejectEntity.setStoreName(record.getStoreName());//退货仓库名称
            rejectEntity.setRejectStatus(VenGoodsRejectStatusEnum.REJECTING.getValue());  //退货单状态 1=退货中
            rejectEntity.setCheckStatus(VenGoodsCheckStatusEnum.REJECT_CHECKING.getValue());  //审核状态 2=待退货审核
            rejectEntity.setRejectReason(record.getAfterSaleReason()); //退货原因
            rejectEntity.setCreateUser(record.getModifyUser()); //创建人
            rejectEntity.setModifyUser(record.getModifyUser()); //修改人
            rejectEntity.setDelFlag(VenDelEnum.NO.getValue()); //删除标识

            // TODO: 2017/6/23 0023  插入退货单日志信息
            //插入退货单信息
            flag = rejectWriterMapper.insert(rejectEntity);
            if (flag <= 0) {
                log.error("插入退货单信息失败,{}", ToStringBuilder.reflectionToString(rejectEntity));
                throw new Exception();
            }
            //插入退货单明细信息
            //退货单明细批量插入List
            List<Map<String, Object>> orderRejectDetailList = new ArrayList<>();
            for (XeVenAfterSaleDetailEntity xeAfterSaleDetail : afterSaleDetailList) {
                XeVenGoodsRejectDetailEntity rejectDetail = new XeVenGoodsRejectDetailEntity();
                rejectDetail.setRejectCode(rejectCode); //退货单号
                rejectDetail.setProSku(xeAfterSaleDetail.getProSku()); //商品sku
                rejectDetail.setBuyNum(xeAfterSaleDetail.getPurchaseNum());//购买数量
                rejectDetail.setRealSendNum(xeAfterSaleDetail.getRealSendNum()); //实际发货数量
                rejectDetail.setRejectNum(xeAfterSaleDetail.getRejectNum()); //退货数量
                rejectDetail.setFinishNum(new BigDecimal(0)); //已退货数量
                rejectDetail.setRefundAmount(xeAfterSaleDetail.getRejectAmount()); //退款金额
                rejectDetail.setProCostPrice(xeAfterSaleDetail.getProCostPrice()); //商品成交价
                Map rejectDetailMap = JSON.parseObject(JSON.toJSONString(rejectDetail, SerializerFeature.WriteMapNullValue,
                        SerializerFeature.WriteNullStringAsEmpty), Map.class);
                orderRejectDetailList.add(rejectDetailMap);
            }
            flag = rejectDetailWriteMapper.insertAllGoodsRejectDetail(orderRejectDetailList);
            //插入退货单日志  // TODO: 2017/6/23 0023 插入退货单日志
        }
        return flag;
    }


    /**
     * @Author:chenjing
     * @Description:审核退款单
     * @Date:上午 10:53 2017/6/27 0027
     * @params: * @param null
     * @return:
     */
    @Override
    public int batchRefund(String refundCode, String refundStatus) throws Exception {
        return 0;
    }

    /**
     * @Author:chenjing
     * @Description: 根据售后单号 订单号查询订单详细信息
     * @Date:下午 4:11 2017/7/1 0001
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenAfterSaleDetailView> getOrderDetial(XeVenAfterSaleDetailForm form) throws Exception {

        List<XeVenAfterSaleDetailEntity> detailList = afterSaleDetailReadMapper.queryAfterSaleDetailList(form.getAfterSalesCode());
        List<XeVenAfterSaleDetailView> viewList = JSON.parseObject(JSON.toJSONString(detailList, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty), List.class);
        return viewList;
    }

    /**
     * @Author:chenjing
     * @Description:批量审核售后单
     * @Date:下午 5:02 2017/7/3 0003
     * @params: * @param null
     * @return:
     */
    @Transactional(value = "writeTransactionManager")
    @Override
    public int batchAfterSalesList(XeVenAfterSaleCheckForm form) throws Exception {
        int flag = 0;
        //如果为审核不通过，直接返回
        if (VenAfterSaleStatusEnum.BACKED.getValue().equals(form.getCheckStatus())) {
            flag = writerMapper.batchAfterSalesList(form);
            if (flag <= 0) {
                log.error("更新售后单信息失败,{}", ToStringBuilder.reflectionToString(form));
                throw new Exception();
            }
            //插入售后单日志   // TODO: 2017/6/23 0023 插入售后单日志
            log.info("售后单共审核{}条,状态置为不通过", flag);
            return flag;
        }
        String[] formCodes = form.getFormCodes(); //审核的售后单单号
        //获取待审核的售后单列表
        List<XeVenAfterSaleEntity> afterSaleList = readMapper.queryAfterSaleListByCods(form.getFormCodes(), form.getUserCode());
        //类型为仅退款的售后单列表
        List<XeVenAfterSaleEntity> refundAfterSaleList = new ArrayList<>();
        //类型为退款退货的售后单列表
        List<XeVenAfterSaleEntity> rejectAfterSaleList = new ArrayList<>();
        for (XeVenAfterSaleEntity entity : afterSaleList) {
            if (VenAfterSaleTypeEnum.REFUND.getValue().equals(entity.getAfterSaleType()))
                refundAfterSaleList.add(entity);
            else if (VenAfterSaleTypeEnum.REJECT.getValue().equals(entity.getAfterSaleType()))
                rejectAfterSaleList.add(entity);
        }
        //获取待审核售后单对应的售后单明细列表
        List<XeVenAfterSaleDetailEntity> afterSaleDetailList = afterSaleDetailReadMapper.queryAfterSaleDetailListByCodes(form.getFormCodes(), form.getUserCode());
        flag = writerMapper.batchAfterSalesList(form);
        if (flag <= 0) {
            log.error("售后单状态异常！更新售后单信息失败,{}", ToStringBuilder.reflectionToString(form));
            throw new Exception();
        }
        log.info("售后单共审核{}条,准备批量插入退款单相关信息", flag);
        if (refundAfterSaleList.size() > 0) {
            //批量插入退款单，退款单明细信息
            flag = insertAllRefund(refundAfterSaleList, afterSaleDetailList, form.getModifyUser());
            if (flag <= 0) {
                log.error("批量插入退款单明细异常！");
                throw new Exception();
            }
        }
        if (rejectAfterSaleList.size() > 0) {
            //批量插入退货单信息
            flag = insertAllReject(rejectAfterSaleList, afterSaleDetailList, form.getModifyUser());
            if (flag <= 0) {
                log.error("批量插入退货单明细异常！");
                throw new Exception();
            }
        }
        return flag;
    }

    /**
     * @Author:chenjing
     * @Description: 批量删除售后单
     * @Date:上午 10:45 2017/7/7 0007
     * @params: * @param null
     * @return:
     */
    @Override
    public int delAfterSaleList(XeVenAfterSaleDelForm form) throws Exception {
        return writerMapper.delAfterSaleList(form);
    }

    /**
     * @Author:chenjing
     * @Description: 批量作废售后单
     * @Date:上午 10:45 2017/7/7 0007
     * @params: * @param null
     * @return:
     */
    @Override
    public int cancelAfterSaleList(XeVenAfterSaleDelForm form) throws Exception {
        return writerMapper.cancelAfterSaleList(form);
    }

    /**
     * @Author:chenjing
     * @Description: 根据订单号查询订单明细中每个商品的已退款金额和已退货数量
     * @Date:16:18 2017/8/1
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenRejectRefundDetailView> getRefundAndReject(Map paramMap) {
        return afterSaleDetailReadMapper.queryRejectRefundDetail(paramMap.get("orderId").toString(), paramMap.get("userCode").toString(), null == paramMap.get("afterSaleCode") ? "" : paramMap.get("afterSaleCode").toString());
    }

    /**
     * @Author:chenjing
     * @Description:根据售后单号查询售后单信息 带订单信息（编辑售后单时使用）
     * @Date:11:50 2017/8/3
     * @params: * @param null
     * @return:
     */
    @Override
    public XeVenAfterSaleInfoView queryAfterSaleInfo(XeVenAfterSaleDetailForm form) throws Exception {
        //获取售后单信息
        XeVenAfterSaleInfoView view = readMapper.queryAfterSaleInfo(form.getAfterSalesCode(), form.getUserCode());
        //根据售后单号查询售后单相关的附件图片地址集合
        List<String> imgs = xeVenAfterSaleImgReadMapper.getImgsByAfterSaleCode(form.getAfterSalesCode());
        if(imgs!=null) view.setImgs(imgs);
        //根据售后单信息获取售后单明细信息
        List<XeVenAfterSaleDetailEntity> detailEntities =
                afterSaleDetailReadMapper.queryAfterSaleDetailList(view.getAfterSalesCode());
        //根据订单号查询已退金额和已退数量
        List<XeVenRejectRefundDetailView> viewList =
                afterSaleDetailReadMapper.queryRejectRefundDetail(view.getOrderId(), form.getUserCode(), form.getAfterSalesCode());
        //封装后返回页面的数据
        List<XeVenAfterSaleDetailView> detailList = new ArrayList<>();
        for (XeVenAfterSaleDetailEntity entity : detailEntities) {
            XeVenAfterSaleDetailView detailView1 = JSON.parseObject(JSON.toJSONString(entity), XeVenAfterSaleDetailView.class);
            for (XeVenRejectRefundDetailView detailView : viewList) {
                if (entity.getProSku().equals(detailView.getProSku())) {
                    detailView1.setRealRefundAmount(detailView.getRealRefundAmount());
                    detailView1.setRealRejectNum(detailView.getRealRejectNum());
                }
            }
            detailList.add(detailView1);
        }
        view.setDetailViewList(detailList);
        return view;
    }

    /**
     * @Author:chenjing
     * @Description:查询订单列表
     * @Date:17:58 2017/8/3
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenAfterSaleOrderView> queryAfterSaleOrderList(XeVenAfterSaleOrderQueryForm form) {
        return orderReadMapper.queryOrderListForAfterSale(form);
    }

    /**
     * @Author:chenjing
     * @Description:根据订单号查询订单明细信息
     * @Date:19:21 2017/8/3
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenAfterSaleDetailView> queryOrderInfoDetail(XeVenAfterSaleDetailForm form) {
        Map map = new HashedMap();
        map.put("orderId", form.getOrderId());
        map.put("userCode", form.getUserCode());
        //根据订单号查询此订单详细信息
        List<XeVenOrderInfoDetailEntity> detailEntites = orderReadMapper.getOrderDetailByParam(map);
        List<XeVenAfterSaleDetailView> afterSaleDetailList = new ArrayList<>();
        List<XeVenRejectRefundDetailView> dv = afterSaleDetailReadMapper.queryRejectRefundDetail(form.getOrderId(), form.getUserCode(), "");
        for (XeVenOrderInfoDetailEntity entity : detailEntites) {
            //根据订单号查询该订单下商品的已退金额和已退数量
            XeVenAfterSaleDetailView detailView = JSON.parseObject(JSON.toJSONString(entity), XeVenAfterSaleDetailView.class);
            for (XeVenRejectRefundDetailView rrd : dv) {
                if (rrd.getProSku().equals(entity.getProSku())) {
                    detailView.setRealRejectNum(rrd.getRealRejectNum());
                    detailView.setRealRefundAmount(rrd.getRealRefundAmount());
                }
            }
            afterSaleDetailList.add(detailView);
        }
        return afterSaleDetailList;
    }

    /**
     * @Author:chenjing
     * @Description: 批量插入退款信息和退款明细信息
     * @Date:下午 7:21 2017/7/4 0004
     * @params: * @param null
     * @return:
     */
    private int insertAllRefund(List<XeVenAfterSaleEntity> afterSaleList, List<XeVenAfterSaleDetailEntity> afterSaleDetailList, String modifyUser) throws Exception {
        int flag = 0;
        //批量插入退款单信息
        List<Map<String, Object>> refundList = new ArrayList<>();
        //批量插入退款单明细信息
        List<Map<String, Object>> refundDetailList = new ArrayList<>();
        for (XeVenAfterSaleEntity record : afterSaleList) {
            XeVenOrderRefundEntity refundEntity = new XeVenOrderRefundEntity();
            String refundCode = financeSeqUtil.createRefundCode(); //退款单号
            refundEntity.setAfterSalesCode(record.getAfterSalesCode());//售后单号
            refundEntity.setOrderId(record.getOrderId()); //订单号
            refundEntity.setRefundSource(VenOrderRefundSourceEnum.AFTER_SALE.getValue());  //退款单来源 2售后创建
            refundEntity.setRefundCode(refundCode);  //退款单号
            refundEntity.setRefundedAmount(new BigDecimal(0)); //已退款金额
            refundEntity.setRealRefundedAmount(record.getRefundAmount()); //退款金额
            refundEntity.setRefundType(VenOrderRefundTypeEnum.AFTERSALERFUND.getValue());   //退款类型 3仅退款
            refundEntity.setRefundReason(VenOrderRefundReasonEnum.NO_REISION.getValue());//退款原因
            refundEntity.setRefundStatus(VenOrderRefundStatusEnum.PENDING.getValue()); //退款状态
            refundEntity.setCreateUser(modifyUser);
            refundEntity.setModifyUser(modifyUser);
            refundEntity.setDelFlag(VenDelEnum.NO.getValue());
            refundEntity.setUserCode(record.getUserCode());
            Map refundMap = JSON.parseObject(JSON.toJSONString(refundEntity, SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteNullStringAsEmpty), Map.class);
            refundList.add(refundMap);

            //生成并插入退款明细信息
            for (XeVenAfterSaleDetailEntity afterSaleDetail : afterSaleDetailList) {
                if (afterSaleDetail.getAfterSalesCode().equals(record.getAfterSalesCode())) {
                    XeVenOrderRefundDetailEntity orderRefundDetail = new XeVenOrderRefundDetailEntity();
                    orderRefundDetail.setRefundCode(refundCode); //退款单号
                    orderRefundDetail.setProSku(afterSaleDetail.getProSku()); //商品sku
                    orderRefundDetail.setBuyNums(afterSaleDetail.getPurchaseNum()); //购买数量
                    orderRefundDetail.setRejectNums(afterSaleDetail.getRejectNum()); //退货数量（如果为售后单为仅退款，则此处为0）
                    orderRefundDetail.setRefundAmount(afterSaleDetail.getRejectAmount()); //退款金额
                    Map afterSaleDetailMap = JSON.parseObject(JSON.toJSONString(orderRefundDetail, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty), Map.class);
                    refundDetailList.add(afterSaleDetailMap);
                }
            }
        }
        log.info("退款单和退款单明细信息封装完毕，开始插入退款单信息,退款单列表共{}条，具体={}", refundList.size(), refundList);
        // TODO: 2017/7/4 0004 退款单日志信息
        //插入退款单信息
        flag = refundWriteMapper.insertAllOrderRefund(refundList);
        if (flag <= 0) {
            log.error("批量插入退款单错误！{}", ToStringBuilder.reflectionToString(refundList));
            throw new Exception();
        }
        log.info("退款单批量插入完毕！共插入{}条", flag);
        log.info("开始插入退款单明细信息,退款单明细列表共{}条，具体={}", refundDetailList.size(), refundDetailList);
        //插入退款明细信息
        flag = orderRefundDetailWriterMapper.insertAllOrderRefundDetail(refundDetailList);
        log.info("退款单明细批量插入完毕！共插入{}条", flag);
        return flag;
    }

    /**
     * @Author:chenjing
     * @Description:批量插入退货单信息 退货单详细信息
     * @Date:下午 7:48 2017/7/4 0004
     * @params: * @param null
     * @return:
     */
    private int insertAllReject(List<XeVenAfterSaleEntity> afterSaleList, List<XeVenAfterSaleDetailEntity> afterSaleDetailList, String modifyUser) throws Exception {
        int flag = 0;
        //批量插入退货单信息
        List<Map<String, Object>> rejectList = new ArrayList<>();
        //批量插入退货单明细信息
        List<Map<String, Object>> rejectDetailList = new ArrayList<>();
        for (XeVenAfterSaleEntity record : afterSaleList) {
            //生成退货单单号
            String rejectCode = storeHouseSeqUtil.createRejectCode();
            //插入退货单信息
            XeVenGoodsRejectEntity rejectEntity = new XeVenGoodsRejectEntity();
            rejectEntity.setAfterSalesCode(record.getAfterSalesCode());  //售后单号
            rejectEntity.setRejectCode(rejectCode);
            //供应商编码
            rejectEntity.setUserCode(record.getUserCode());
            rejectEntity.setOrderId(record.getOrderId());  //订单号
            //仓库标识
            String storeId = "";                            //// TODO: 2017/6/23 0023 退货仓库信息确认
            rejectEntity.setRejectStatus(VenGoodsRejectStatusEnum.REJECTING.getValue());  //退货单状态 1=退货中
            rejectEntity.setCheckStatus(VenGoodsCheckStatusEnum.REJECT_CHECKING.getValue());  //审核状态 2=待退货审核
            rejectEntity.setRejectReason(record.getAfterSaleReason()); //退货原因
            rejectEntity.setCreateUser(modifyUser); //创建人
            rejectEntity.setModifyUser(modifyUser); //修改人
            rejectEntity.setDelFlag(VenDelEnum.NO.getValue()); //删除标识
            Map rejectMap = JSON.parseObject(JSON.toJSONString(rejectEntity, SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteNullStringAsEmpty), Map.class);
            rejectList.add(rejectMap);

            //生成退货单明细信息
            for (XeVenAfterSaleDetailEntity xeAfterSaleDetail : afterSaleDetailList) {
                if (xeAfterSaleDetail.getAfterSalesCode().equals(record.getAfterSalesCode())) {
                    XeVenGoodsRejectDetailEntity rejectDetail = new XeVenGoodsRejectDetailEntity();
                    rejectDetail.setRejectCode(rejectCode); //退货单号
                    rejectDetail.setProSku(xeAfterSaleDetail.getProSku()); //商品sku
                    rejectDetail.setBuyNum(xeAfterSaleDetail.getPurchaseNum());//购买数量
                    rejectDetail.setRealSendNum(xeAfterSaleDetail.getRealSendNum()); //实际发货数量
                    rejectDetail.setRejectNum(xeAfterSaleDetail.getRejectNum()); //退货数量
                    rejectDetail.setFinishNum(new BigDecimal(0)); //已退货数量
                    rejectDetail.setProCostPrice(xeAfterSaleDetail.getProCostPrice()); //商品成交价
                    rejectDetail.setRefundAmount(xeAfterSaleDetail.getRejectAmount()); //退款金额
                    Map rejectDetailMap = JSON.parseObject(JSON.toJSONString(rejectDetail, SerializerFeature.WriteMapNullValue,
                            SerializerFeature.WriteNullStringAsEmpty), Map.class);
                    rejectDetailList.add(rejectDetailMap);
                }
            }
        }
        log.info("退货单和退货单明细信息封装完毕，开始插入退货单信息,退货单列表共{}条，具体={}", rejectList.size(), rejectList);
        // TODO: 2017/7/4 0004 退货单日志信息 
        //批量插入退货单信息
        flag = rejectWriterMapper.insertAllGoodsReject(rejectList);
        if (flag <= 0) {
            log.error("批量插入退货单信息错误！{}", ToStringBuilder.reflectionToString(rejectList));
            throw new Exception();
        }
        log.info("退货单批量插入完毕！共插入{}条", flag);
        log.info("开始插入退货单明细信息,退货单明细列表共{}条，具体={}", rejectDetailList.size(), rejectDetailList);
        //批量插入退货单明细信息
        flag = rejectDetailWriteMapper.insertAllGoodsRejectDetail(rejectDetailList);
        log.info("退货单明细批量插入完毕！共插入{}条", flag);
        return flag;
    }

    @Override
    public Long selectAfterSaleByOrderId(String orderId) {

        return readMapper.selectAfterSaleByOrderId(orderId);
    }


}
